﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cloak.NUnit;
using Cloak.Reflection;
using Moq;
using NUnit.Framework;
using Ruleweaver.Rules;

namespace Ruleweaver.Conditions.Schemas
{
	public class ChangeDefaultDeclarationNames : Behavior
	{
		private CheckRule _rule;
		private string _newDefaultName = "NewDefault";
		private string _nonDefaultName = "NonDefault";
		private IConditionDeclaration _declaration;
		private Condition _defaultCondition;
		private Condition _nonDefaultCondition;

		protected override void Given()
		{
			_rule = Rule.Check(Reflect.Func<ICheckable<int>, Check<int>>(Checkable.IsPositive));

			var initialDefaultCondition = new Condition(_rule, typeof(int));
			var initialNonDefaultCondition = new Condition(_rule, typeof(int), _nonDefaultName);

			var declarationMock = new Mock<IConditionDeclaration>();

			declarationMock
				.Setup(declaration => declaration.GetConditions(typeof(int)))
				.Returns(() => new[] { initialDefaultCondition, initialNonDefaultCondition });

			_declaration = declarationMock.Object;
		}

		protected override void When()
		{
			var declarationWithDefaultName = new[] { _declaration }.WithDefaultName(_newDefaultName).Single();

			var conditions = declarationWithDefaultName.GetConditions(typeof(int)).ToList();

			_defaultCondition = conditions[0];
			_nonDefaultCondition = conditions[1];
		}

		[Then]
		public void DefaultNamesChange()
		{
			Assert.IsTrue(_defaultCondition.Key.NameEquals(_newDefaultName));
		}

		[Then]
		public void DefaultTypesDoNotChange()
		{
			Assert.AreEqual(typeof(int), _defaultCondition.Key.TargetType);
		}

		[Then]
		public void DefaultRulesDoNotChange()
		{
			Assert.AreEqual(_rule, _defaultCondition.Rule);
		}

		[Then]
		public void NonDefaultNamesDoNotChange()
		{
			Assert.IsTrue(_nonDefaultCondition.Key.NameEquals(_nonDefaultName));
		}

		[Then]
		public void NonDefaultTypesDoNotChange()
		{
			Assert.AreEqual(typeof(int), _nonDefaultCondition.Key.TargetType);
		}

		[Then]
		public void NonDefaultRulesDoNotChange()
		{
			Assert.AreEqual(_rule, _nonDefaultCondition.Rule);
		}
	}
}